package marchingCubes;

import java.util.List;
import java.util.Vector;

import simpleGeom.Box3D;
import simpleGeom.HasBounds3D;
import simpleGeom.TrianglePreCalc;

public class OctCell extends Box3D implements IsMCVertex {
	OctCell[] childs=null;
	public static int maxgeneration;
	public static float minD;
	//float  maxD;
	int id;
	public int generation=0;
	public float value=Float.MAX_VALUE;
	MCube cube;
	public OctCell(float x1, float y1, float z1, float x2, float y2, float z2) {
		super(x1, y1, z1, x2, y2, z2);
		init();
		// TODO Auto-generated constructor stub
	}
	public void init(){
		/*this.cX=x2-x1;
		this.cY=y2-y1;
		this.cZ=z2-z1;*/
	}

	/*float cX;
	float cY;
	float cZ;*/
	public int getIndex(int x,int y,int z){
		return x+y*2+z*4;
	}
	public OctCell getChild(int x,int y,int z){
		return childs[getIndex(x,y,z)];
	}
	public void setChild(int x,int y,int z, OctCell cell){
		childs[getIndex(x,y,z)]=cell;
	}

	

	public OctCell getCell(float x, float y, float z) {
		int xK = 0;
		int yK = 0;
		int zK = 0;
		
		if (x > x2 || x < x1)
			return null;
		if (y > y2 || y < y1)
			return null;
		if (z > z2 || z < z1)
			return null;
		
		
		if (generation==maxgeneration)
			return this;
		
		if (x > getCenterX())
			xK = 1;
		if (y > getCenterY())
			yK = 1;
		if (z > getCenterZ())
			zK = 1;
		if (childs == null)return null;
		OctCell cell = getChild(xK,yK,zK);
		
		return cell.getCell(x, y, z);
	}

	public void collectAllEndChildren(Vector<OctCell> collection) {
		if (childs != null) {
			for (int i=0;i<childs.length;i++) {
			OctCell cell = childs[i];
			if (cell!=null){
				cell.collectAllEndChildren(collection);
			}	
			}
		}
		else if (generation==maxgeneration){
			collection.add(this);
		}
	}
	public void insert(Box3D bounds,TrianglePreCalc cObject) {
		Box3D cB=cObject.getBounds3D();
		if (!isOverlap(cB)) {
			return;
		}
		if (generation==maxgeneration){
			TrianglePreCalc cD=(TrianglePreCalc)cObject;
			float planeDist=cD.getDistancePlane(getCenterX(), getCenterY(), getCenterZ());
			if (planeDist<value){
			float cDist=cD.getDistance(getCenterX(), getCenterY(), getCenterZ());
			if (cDist<value){
				value=cDist;
			}
			}
			return;
		}
		if (childs==null){
			childs = new OctCell[8];
			float dX = this.getDimX() * 0.5f;
			float dY = this.getDimY() * 0.5f;
			float dZ = this.getDimZ() * 0.5f;
			
			for (int x = 0; x < 2; x++) {
				for (int y = 0; y < 2; y++) {
					for (int z = 0; z < 2; z++) {
						
						OctCell child = new OctCell();
						

						child.x1 = x * dX + x1;
						child.y1 = y * dY + y1;
						child.z1 = z * dZ + z1;

						child.x2 = child.x1 + dX;
						child.y2 = child.y1 + dY;
						child.z2 = child.z1 + dZ;
						child.generation=generation+1;
						if (child.isOverlap(cB)){
							setChild(x,y,z,child);
						}
					}
				}
			}
		}
		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < 2; y++) {
				for (int z = 0; z < 2; z++) {
					OctCell child=getChild(x,y,z);
					if (child!=null){
					child.insert(bounds,cObject);
					}
				}
			}
		}
	}
	
	public OctCell() {
		super();
		// TODO Auto-generated constructor stub
	}

	public float getZ() {
		// TODO Auto-generated method stub
		return getCenterZ();
	}

	public void setPosition(float x, float y, float z) {
		// TODO Auto-generated method stub

	}

	public void setZ(float z) {
		// TODO Auto-generated method stub

	}

	public float getX() {
		// TODO Auto-generated method stub
		return getCenterX();
	}

	public float getY() {
		// TODO Auto-generated method stub
		return getCenterY();
	}

	public void setPosition(float x, float y) {
		// TODO Auto-generated method stub

	}

	public void setX(float x) {
		// TODO Auto-generated method stub

	}

	public void setY(float Y) {
		// TODO Auto-generated method stub

	}

	public int getId() {
		// TODO Auto-generated method stub
		return id;
	}

	public void setId(int i) {
		// TODO Auto-generated method stub
		this.id = id;
	}

	public float getValue() {
		// TODO Auto-generated method stub
		return value;
	}

	public MCube getCube() {
		// TODO Auto-generated method stub
		return cube;
	}

	public void setCube(MCube cube) {
		// TODO Auto-generated method stub
		this.cube = cube;
	}
	
}
